import {fromJS, List, Map} from 'immutable';
import {expect} from 'chai';

import * as folderStore from '../src/core';

describe('application logic', () => {
    var folderTree = {
        id: "1",
        name: "folder1",
        children: [{
            id: "11",          
            name: "folder11",
            children: [{               
                id: "111",
                name: "folder111",
            }, {                
                id: "112",
                name: "folder112",
            }]
        }]
    }
   
    it('adds the folder tree to the state', () => {
        var state = Map();
        const tree = fromJS(folderTree);
        const nextState = folderStore.setFolderTree(state, tree);
        expect(nextState).to.equal(Map({
            folderTree: fromJS(folderTree),
        }));
    });
  

    describe('getKeyPath', () => {
        it('if folder no exsited should return false', () => {
            const folderTreeState = fromJS(folderTree);
            const keyPath = folderStore.getKeyPath(folderTreeState, "12");
            expect(keyPath).to.equal(false);
        })

        it('get folder key path in folder tree', () => {
            const folderTreeState = fromJS(folderTree);
            let keyPath = folderStore.getKeyPath(folderTreeState, "11");
            expect(List(keyPath)).to.equal(List(["children", 0]));
            keyPath = folderStore.getKeyPath(folderTreeState, "112");
            expect(List(keyPath)).to.equal(List(["children", 0, "children", 1]));
        })     


        it('if id indicate the root should return []', () =>{
            const folderTreeState = fromJS(folderTree);
            const keyPath = folderStore.getKeyPath(folderTreeState, "1");
            expect([]).to.eql([]);
        })  
    })

    describe('addNode', () => {
        it('add a folder', () => {
            const folderTreeState = fromJS(folderTree);
            const newFolder = {                
                id: "113",
                name: "folder113",
            }
            const nextState = folderStore.addNode(folderTreeState, "11", newFolder);

            var newFolderTree = {
                    id: "1",
                    name: "folder1",
                    children: [{
                        id: "11",                       
                        name: "folder11",
                        children: [{                           
                            id: "111",
                            name: "folder111",
                        }, {                           
                            id: "112",
                            name: "folder112",
                        }, {                           
                            id: "113",
                            name: "folder113",
                        }]
                    }]
                }
                //folderTree.children[0].children.push(newFolder);
            expect(nextState).to.equal(fromJS(newFolderTree))
        })

        it('add a folder to not existed parent folder', () => {
            const folderTreeState = fromJS(folderTree);
            const newFolder = {               
                id: "113",
                name: "folder113",
            }

            let nextState = null;
            expect(() => {
                nextState = folderStore.addNode(folderTreeState, "12", newFolder);
            }).to.throw("parentId is invalidate!");
        })

        it('add a folder to parent folder that is empty', () => {
            const folderTreeState = fromJS(folderTree);
            const newFolder = {              
                id: "113",
                name: "folder113",
            }

            var newFolderTree = {
                id: "1",
                name: "folder1",
                children: [{
                    id: "11",                   
                    name: "folder11",
                    children: [{                       
                        id: "111",
                        name: "folder111",
                    }, {                      
                        id: "112",
                        name: "folder112",
                        children: [{                           
                            id: "113",
                            name: "folder113",
                        }]
                    }]
                }]
            }

            const nextState = folderStore.addNode(folderTreeState, "112", newFolder);
            expect(nextState).to.equal(fromJS(newFolderTree))
        })       
    })

    describe('removeNode', ()=>{
        it('remove a folder', ()=>{
            const folderTreeState = fromJS(folderTree);           
            const nextState = folderStore.removeNode(folderTreeState, "112");

            var newFolderTree = {
                    id: "1",
                    name: "folder1",
                    children: [{
                        id: "11",                      
                        name: "folder11",
                        children: [{                           
                            id: "111",
                            name: "folder111",
                        }]
                    }]
                }
                //folderTree.children[0].children.push(newFolder);
            expect(nextState).to.equal(fromJS(newFolderTree))
        })
    })

    describe('setFolderChilren', ()=>{
        var folderChildren = {
            id : "11",
            data: [{
                id: "111",
                name: "folder111",
                type: "cmis:folder"
            }, {
                id: "112",
                name: "folder112",
                type: "cmis:folder"
            },{
                id: "113",
                name: "folder113",
                type: "cmis:document"
            }, {
                id: "114",
                name: "folder114",
                type: "cmis:other"
            }]
        }
        it('set folder children', () => {
            const folderTreeState = fromJS(folderTree);  
            const nextState = folderStore.setFolderChildren(folderTreeState, "11", fromJS(folderChildren.data));

            var newfolderTree = {
                id: "1",
                name: "folder1",
                children: [{
                    id: "11",                   
                    name: "folder11",
                    children: [{
                        id: "111",
                        name: "folder111",
                        type: "cmis:folder"
                    }, {
                        id: "112",
                        name: "folder112",
                        type: "cmis:folder"
                    }, {
                        id: "113",
                        name: "folder113",
                        type: "cmis:document"
                    }, {
                        id: "114",
                        name: "folder114",
                        type: "cmis:other"
                    }]
                }]
            }          
                //folderTree.children[0].children.push(newFolder);
            expect(nextState).to.equal(fromJS(newfolderTree))
        })
    })    

    describe('getFolderById', ()=>{
       
        it('get folder by id', () => {
            const folderTreeState = fromJS(folderTree);      
            const retFolder0 = folderStore.getFolderById(folderTreeState, "1");      
            const retFolder1 = folderStore.getFolderById(folderTreeState, "112");
            const retFolder2 = folderStore.getFolderById(folderTreeState, "11");           

            var folder1 = {              
                id: "112",
                name: "folder112",
            }

            var folder2 = {
                id: "11",              
                name: "folder11",
                children: [{                   
                    id: "111",
                    name: "folder111",
                }, {                  
                    id: "112",
                    name: "folder112",
                }]
            }
            expect(retFolder0).to.equal(fromJS(folderTree));
            expect(retFolder1).to.equal(fromJS(folder1));
            expect(retFolder2).to.equal(fromJS(folder2));
        })        
    })

    describe('getFolderPath', ()=>{
        var folderChildren = {
            id : "11",
            data: [{
                id: "111",
                name: "folder111",
                type: "cmis:folder"
            }, {
                id: "112",
                name: "folder112",
                type: "cmis:folder"
            },{
                id: "113",
                name: "folder113",
                type: "cmis:document"
            }, {
                id: "114",
                name: "folder114",
                type: "cmis:other"
            }]
        }
        it('get folder path', () => {
            const folderTreeState = fromJS(folderTree);  
            const path = folderStore.getFolderPath(folderTreeState, "11");

            var newfolderTree = [{
                id: "11",
                name: "folder11",
                children: [{
                    id: "111",
                    name: "folder111",
                }, {
                    id: "112",
                    name: "folder112",
                }]
            }, {
                id: "1",
                name: "folder1",
                children: [{
                    id: "11",
                    name: "folder11",
                    children: [{
                        id: "111",
                        name: "folder111",
                    }, {
                        id: "112",
                        name: "folder112",
                    }]
                }]
            }]
                    
                //folderTree.children[0].children.push(newFolder);
            expect(path).to.equal(fromJS(newfolderTree))
        })

        it('get root folder path', () => {
            const folderTreeState = fromJS(folderTree);  
            const path = folderStore.getFolderPath(folderTreeState, "1");
            var newfolderTree = [{
                id: "1",
                name: "folder1",
                children: [{
                    id: "11",
                    name: "folder11",
                    children: [{
                        id: "111",
                        name: "folder111",
                    }, {
                        id: "112",
                        name: "folder112",
                    }]
                }]
            }]
                    
                //folderTree.children[0].children.push(newFolder);
            expect(path).to.equal(fromJS(newfolderTree))
        })
    }) 


/*
  describe('next', () => {

    it('takes the next two entries under vote', () => {
      const state = Map({
        entries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
      });
      const nextState = next(state);
      expect(nextState).to.equal(Map({
        vote: Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later')
        }),
        entries: List.of('Sunshine')
      }));
    });

    it('puts winner of current vote back to entries', () => {
      expect(
        next(Map({
          vote: Map({
            round: 1,
            pair: List.of('Trainspotting', '28 Days Later'),
            tally: Map({
              'Trainspotting': 4,
              '28 Days Later': 2
            })
          }),
          entries: List.of('Sunshine', 'Millions', '127 Hours')
        }))
      ).to.equal(
        Map({
          vote: Map({
            round: 2,
            pair: List.of('Sunshine', 'Millions')
          }),
          entries: List.of('127 Hours', 'Trainspotting')
        })
      );
    });

    it('puts both from tied vote back to entries', () => {
      expect(
        next(Map({
          vote: Map({
            round: 1,
            pair: List.of('Trainspotting', '28 Days Later'),
            tally: Map({
              'Trainspotting': 3,
              '28 Days Later': 3
            })
          }),
          entries: List.of('Sunshine', 'Millions', '127 Hours')
        }))
      ).to.equal(
        Map({
          vote: Map({
            round: 2,
            pair: List.of('Sunshine', 'Millions')
          }),
          entries: List.of('127 Hours', 'Trainspotting', '28 Days Later')
        })
      );
    });

    it('marks winner when just one entry left', () => {
      expect(
        next(Map({
          vote: Map({
            round: 1,
            pair: List.of('Trainspotting', '28 Days Later'),
            tally: Map({
              'Trainspotting': 4,
              '28 Days Later': 2
            })
          }),
          entries: List()
        }))
      ).to.equal(
        Map({
          winner: 'Trainspotting'
        })
      );
    });

  });

  describe('restart', () => {

    it('returns to initial entries and takes the first two entries under vote', () => {
      expect(
        restart(Map({
          vote: Map({
            round: 1,
            pair: List.of('Trainspotting', 'Sunshine')
          }),
          entries: List(),
          initialEntries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
        }))
      ).to.equal(
        Map({
          vote: Map({
            round: 2,
            pair: List.of('Trainspotting', '28 Days Later')
          }),
          entries: List.of('Sunshine'),
          initialEntries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
        })
      );
    });

  });

  describe('vote', () => {

    it('creates a tally for the voted entry', () => {
      expect(
        vote(Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later')
        }), 'Trainspotting', 'voter1')
      ).to.equal(
        Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later'),
          tally: Map({
            'Trainspotting': 1
          }),
          votes: Map({
            voter1: 'Trainspotting'
          })
        })
      );
    });

    it('adds to existing tally for the voted entry', () => {
      expect(
        vote(Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later'),
          tally: Map({
            'Trainspotting': 3,
            '28 Days Later': 2
          }),
          votes: Map()
        }), 'Trainspotting', 'voter1')
      ).to.equal(
        Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later'),
          tally: Map({
            'Trainspotting': 4,
            '28 Days Later': 2
          }),
          votes: Map({
            voter1: 'Trainspotting'
          })
        })
      );
    });

    it('nullifies previous vote for the same voter', () => {
      expect(
        vote(Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later'),
          tally: Map({
            'Trainspotting': 3,
            '28 Days Later': 2
          }),
          votes: Map({
            voter1: '28 Days Later'
          })
        }), 'Trainspotting', 'voter1')
      ).to.equal(
        Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later'),
          tally: Map({
            'Trainspotting': 4,
            '28 Days Later': 1
          }),
          votes: Map({
            voter1: 'Trainspotting'
          })
        })
      );
    });

    it('ignores the vote if for an invalid entry', () => {
      expect(
        vote(Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later')
        }), 'Sunshine')
      ).to.equal(
        Map({
          round: 1,
          pair: List.of('Trainspotting', '28 Days Later')
        })
      );
    });

  });
*/
});
